package com.hgl.bi.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hgl.bi.common.constant.BusinessConstant;
import com.hgl.bi.common.constant.ErrorCode;
import com.hgl.bi.common.exception.BusinessException;
import com.hgl.bi.common.manager.COSManager;
import com.hgl.bi.common.utils.AssertUtil;
import com.hgl.bi.web.entity.MetadataEntity;
import com.hgl.bi.web.entity.UserEntity;
import com.hgl.bi.web.mapper.MetadataMapper;
import com.hgl.bi.web.model.dto.FileDto;
import com.hgl.bi.web.model.dto.FileSetDto;
import com.hgl.bi.web.model.dto.PathDto;
import com.hgl.bi.web.model.dto.SignatureDto;
import com.hgl.bi.web.model.vo.SignatureVo;
import com.hgl.bi.web.service.MetadataService;
import com.hgl.bi.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @program: BI
 * @description: 文件元数据管理服务实现层
 * @author: hgl
 * @create: 2025-02-14 16:33
 */
@Service
public class MetadataServiceImpl extends ServiceImpl<MetadataMapper, MetadataEntity>
        implements MetadataService {

    @Autowired
    private COSManager cosManager;

    @Autowired
    private UserService userService;
    
    @Autowired
    private MetadataMapper metadataMapper;
    

    @Override
    public SignatureVo getCosUploadSignature(SignatureDto signatureDto, Long userId) {
        String type = signatureDto.getType();
        String fileName = signatureDto.getFileName();
        // 非空校验
        AssertUtil.notNull(type, ErrorCode.PARAM_ERROR);
        AssertUtil.notNull(fileName, ErrorCode.FILE_NAME_NOT_NULL);
        // 获取用户信息
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<UserEntity>()
                .eq("id", userId);
        UserEntity user = userService.getOne(wrapper);
        String phone = user.getPhone();
        // 构建存储路径
        String cosPath = "";
        if (type.equals("image")) {
            cosPath = String.format("/%s/images/%s", phone, fileName);
        } else if (type.equals("file")) {
            cosPath = String.format("/%s/files/%s", phone, fileName);
        }
        // 获取访问签名
        String signature = cosManager.getUploadSignature(cosPath, BusinessConstant.AN_HOUR);
        return new SignatureVo(cosPath, signature);
    }

    @Override
    public void saveFilePath(PathDto pathDto, Long userId) {
        String cosPath = pathDto.getCosPath();
        Long fileSize = pathDto.getFileSize();
        // 非空校验
        AssertUtil.notNull(cosPath, ErrorCode.COS_PATH_NOT_NULL);
        AssertUtil.notNull(fileSize, ErrorCode.FILE_SIZE_NOT_NULL);
        // 获取文件类型
        String fileType = cosPath.substring(cosPath.lastIndexOf(".") + 1)
                .toLowerCase();

        // 定义支持的图片类型
        String[] imageTypes = {"jpg", "png"};
        // 判断是否为图片
        boolean isImage = false;
        for (String type : imageTypes) {
            if (fileType.equals(type)) {
                isImage = true;
                break;
            }
        }
        // 保存文件路径
        if (isImage) {
            // 若为图片
            UpdateWrapper<UserEntity> userWrapper = new UpdateWrapper<UserEntity>()
                    .eq("id", userId)
                    .set("avatar", cosPath);
            boolean updated = userService.update(userWrapper);
            AssertUtil.isTrue(updated, ErrorCode.UPDATE_FALSE);
        } else {
            // 若为文件
            MetadataEntity metadata = new MetadataEntity();
            metadata.setUserId(userId);
            String fileName = cosPath.substring(cosPath.lastIndexOf("/") + 1, cosPath.lastIndexOf("."));
            metadata.setFileName(fileName);
            metadata.setCosPath(cosPath);
            metadata.setFileSize(fileSize);
            metadata.setFileType(fileType);
            metadata.setUploadTime(new Date());
            boolean saved = save(metadata);
            AssertUtil.isTrue(saved, ErrorCode.SAVE_FALSE);
        }
    }

    @Override
    public List<Map<Integer, String>> getFileContent(Long id) {
        // 获取cosPath
        QueryWrapper<MetadataEntity> wrapper = new QueryWrapper<MetadataEntity>()
                .eq("id", id);
        MetadataEntity metadata = getOne(wrapper);
        String cosPath = metadata.getCosPath();
        // 读取文件内容
        List<Map<Integer, String>> content;
        try {
            content = cosManager.syncReadContent(cosPath);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.READ_FILE_CONTENT_FALSE);
        }
        return content;
    }

    @Override
    public void associateSet(FileSetDto fileSetDto) {
        Long fileId = fileSetDto.getFileId();
        List<Long> setIds = fileSetDto.getSetIds();
        // 非空校验
        AssertUtil.notNull(fileId, ErrorCode.FILE_ID_NULL);
        AssertUtil.notNull(setIds, ErrorCode.SET_ID_NULL);
        // 分配权限
        boolean associated = metadataMapper.associateSet(fileId, setIds);
        AssertUtil.isTrue(associated, ErrorCode.ASSOCIATE_SET_FALSE);
    }

    @Override
    public String getCosDownloadSignature(String cosPath) {

        String signature = cosManager.getDownloadSignature(cosPath, BusinessConstant.AN_HOUR);
        return signature;
    }

    @Override
    public List<Map<Integer, String>> getCleanFileContent(Long id) {
        // 获取cosPath
        QueryWrapper<MetadataEntity> wrapper = new QueryWrapper<MetadataEntity>()
                .eq("id", id);
        MetadataEntity metadata = getOne(wrapper);
        String cosPath = metadata.getCosCsvPath();
        // 读取文件内容
        List<Map<Integer, String>> content;
        try {
            content = cosManager.syncReadContent(cosPath);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.READ_FILE_CONTENT_FALSE);
        }
        return content;
    }

    @Override
    public void removeSets(FileSetDto fileSetDto) {
        Long fileId = fileSetDto.getFileId();
        List<Long> setIds = fileSetDto.getSetIds();
        boolean removed = metadataMapper.removeSets(fileId, setIds);
        AssertUtil.isTrue(removed, ErrorCode.REMOVE_FALSE);
    }

    @Override
    public List<Long> getMyAssociateFiles(long userId, Long id) {
        List<Long> list = metadataMapper.selectMyAssociateFiles(userId, id);
        return list;
    }

    @Override
    public void associateFile(FileDto fileDto) {
        Long setId = fileDto.getSetId();
        List<Long> fileIds = fileDto.getFileIds();

        // 非空校验
        AssertUtil.notNull(fileIds, ErrorCode.FILE_ID_NULL);
        AssertUtil.notNull(setId, ErrorCode.SET_ID_NULL);
        // 分配权限
        boolean associated = metadataMapper.associateFile(setId, fileIds);
        AssertUtil.isTrue(associated, ErrorCode.ASSOCIATE_SET_FALSE);
    }

    @Override
    public void removeFiles(FileDto fileDto) {
        Long setId = fileDto.getSetId();
        List<Long> fileIds = fileDto.getFileIds();
        // 非空校验
        AssertUtil.notNull(fileIds, ErrorCode.FILE_ID_NULL);
        AssertUtil.notNull(setId, ErrorCode.SET_ID_NULL);

        boolean removed = metadataMapper.removeFiles(setId, fileIds);
        AssertUtil.isTrue(removed, ErrorCode.REMOVE_FALSE);
    }
}